package api

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"time"

	"github.com/linclaus/stock/pkg/cache"
	"github.com/linclaus/stock/pkg/common/util"

	"github.com/linclaus/stock/pkg/db"
	"github.com/linclaus/stock/pkg/model"
)

func (s *Server) AddStrategy(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Printf("Failed to read payload: %s\n", err)
		http.Error(w, fmt.Sprintf("Failed to read payload: %s", err), http.StatusBadRequest)
		return
	}

	strategy := &model.Strategy{
		ContactType: "email",
	}
	err = json.Unmarshal(body, strategy)
	util.SetStrategyId(strategy)
	if err != nil || util.Validation(*strategy) != nil {
		fmt.Printf("Failed to Unmarshal strategy: %s\n", err)
		http.Error(w, fmt.Sprintf("Failed to Unmarshal strategy: %s", err), http.StatusBadRequest)
		return
	}
	if _, ok := cache.StockMap.Get(strategy.Code); !ok {
		if util.StockExixts(strategy.Code) {
			s.Codes.Add(strategy.Code)
			StoreCodes(s.Codes)
		} else {
			fmt.Printf("Code:%s doesn't exist\n", strategy.Code)
			http.Error(w, fmt.Sprintf("Code:%s doesn't exist\n", strategy.Code), http.StatusBadRequest)
			return
		}
	}

	cache.StrategyAddChan <- *strategy

	user, err := db.UserMgr.GetUserByEmail(strategy.ContactValue)
	if err != nil || user.Id == 0 {
		user = model.User{
			Email:          strategy.ContactValue,
			MaxStrategyNum: DefaultMaxStrategiesNum,
		}
		db.UserMgr.CreateUser(&user)
		user, _ = db.UserMgr.GetUserByEmail(strategy.ContactValue)
	}
	ept := strategy.ExpiredTime
	if ept.IsZero() {
		ept = time.Now().AddDate(0, 0, DefaultExpiredTime)
	}
	userStrategy := model.UserStrategy{
		UserId:      user.Id,
		StrategyId:  strategy.StrategyId,
		Code:        strategy.Code,
		ExpiredTime: ept,
	}
	db.UserStrategyMgr.CreateUserStrategy(&userStrategy)
}

func (s *Server) DeleteStrategy(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Printf("Failed to read payload: %s\n", err)
		http.Error(w, fmt.Sprintf("Failed to read payload: %s", err), http.StatusBadRequest)
		return
	}
	strategy := &model.Strategy{
		ContactType: "email",
	}
	err = json.Unmarshal(body, strategy)
	util.SetStrategyId(strategy)
	if err != nil || util.Validation(*strategy) != nil {
		fmt.Printf("Failed to Unmarshal strategy: %s\n", err)
		http.Error(w, fmt.Sprintf("Failed to Unmarshal strategy: %s", err), http.StatusBadRequest)
		return
	}

	if _, ok := cache.StockMap.Get(strategy.Code); !ok {
		fmt.Printf("Code:%s doesn't exist\n", strategy.Code)
		http.Error(w, fmt.Sprintf("Code:%s doesn't exist\n", strategy.Code), http.StatusBadRequest)
		return
	}

	cache.StrategyDeleteChan <- *strategy

	user, err := db.UserMgr.GetUserByEmail(strategy.ContactValue)
	if err != nil || user.Id == 0 {
		user = model.User{
			Email: strategy.ContactValue,
		}
		db.UserMgr.CreateUser(&user)
		user, _ = db.UserMgr.GetUserByEmail(strategy.ContactValue)
	}
	userStrategy := model.UserStrategy{
		UserId:     user.Id,
		StrategyId: strategy.StrategyId,
		Code:       strategy.Code,
	}
	db.UserStrategyMgr.DeleteUserStrategy(&userStrategy)
}
